查看原文
其他

遇春:语雀编辑器自研之路

遇春 语雀 2022-11-10

本文为蚂蚁集团语雀自研编辑器技术负责人遇春在语雀大会上的演讲。


大家好,我我叫遇春,接下来由我给大家分享语雀自主研发的编辑器。

在这之前组委会跟我说要分享一下编辑器里面一些技术先进的地方,我就仔细思考这个问题,究竟语雀编辑器中什么技术是先进的。在我看来。技术本身其实不存在所谓的先进技术或者是落后的技术。技术的目的就是为了解决问题,可能会有新旧之分,但是语雀团队又不是一个特别追求新技术的一个团队,所以可能接下来我的分享中主要是针对我们所遇到的具体问题,然后怎么样找解决方案。从问题本身来说,每一个产品他遇到的问题都不一样,所以很难对比说我们的技术就很先进。所以接下来的分享,我们来看看我们语雀编辑器遇到了什么样的问题以及技术上的思考。

先从这一句话开始。文有汝心出,笔墨语雀来。这一句是语雀最早的 slogan。
我们希望当你打开语雀编辑器的时候,能够沉浸在一种平静而又愉悦的创作心流当中。不管你是要写一个周报或者是写个小说,或者旅游回来写一篇游记。我们都希望这个过程是一种享受。当你想要插入一个流程图或者是插一个数据报表,或者想要插一个视频,我们都希望在语雀编辑器当中都能够随手拈来,一气呵成。这就是语雀编辑器所要追求的一个方向。

接下来,我的分享会包含这几个部分


Part 1. 语雀编辑器的家族介绍



七兄弟


先给大家放一张全家福,这是语雀所有编辑器的一个全家福,我们根据时间给大家做了一个排行,老大、老二、老三、老四、老五、老六、老七。



文档编辑器




先从老大文档编辑器开始,能力比较强,人比较老实,然后也肯吃苦,里里外外全靠他,脏活累活全包。可以说有内容输入的地方就有他的身影。我们可以看到包括语雀小记,各种评论区都是他来负责的,基本上可以说没有他就没有这个家。


目录编辑器




老二目录编辑器,可能大家比较惊讶,这也是个编辑器吗?对的,这是一个如假包换的编辑器。因为早年出去读书,然后常年在外不怎么回家,所以大家都不认识他。大学的时候,在图书馆里做过勤工俭学,在分类整理这一块,可是一个一等一的高手。所以这几年回家来打理家务,家里的资料、文件,经他这么一手,把你整理的井井有条。


工作表/数据表




老三工作表,这个哥们天生喜欢数学。家里所有的水费、电费、煤气费,各种吃穿用度,所有的收入开支交给他,保证给你管理的妥妥的。后来他发现自己忙不过来,又有了老七,

老七是我们的数据表,数据表就和现在的小孩子一样,天生的互联网的原住民,他比较喜欢收集数据,他在收集数据这块也是有一手,凭着这一手绝活,将来定是前途无量的。所以和数据有关的事情交给他们,稳!


思维图,流程图和演示文稿




老四老五老六,思维图,流程图和演示文稿,他们是个三胞胎,出生的时候日子过得比较好,营养跟得上,牛奶、鸡蛋每天伺候着,身板硬了心气儿就高,对吧?在图形领域可真是没有怕过谁,不是今天要干翻这个,就是明天要放平那个,正可谓是初生牛犊不怕虎,立志闯出一片天。

七个编辑器,七兄弟齐心协力为大家服务。那么重点来了:

所有的语雀编辑器的所有功能,对所有的用户,不管你是付费的还是免费的,一视同仁,所有的功能都向大家免费开放。


四版本


好的,这么多编辑器肯定说不完。我们接下来挑一些有故事的说,先从文档编辑器说起。


一句话介绍,简约而不简单,包罗万象,普惠大众,语雀文档编辑器经历了四个版本,每一个版本也都给我们留下了一些非常宝贵的特性。


1.0


从 1.0 开始,我们是一个 Markdown 编辑器,熟悉 Markdown 语法的同学都知道。我们可以通过输入一些非常简单的字符,然后实现一些清晰的文档结构。标题,列表,引用等等,非常有利于阅读。这也让我们意识到文档的美,美在结构。而这种快捷输入的能力在我们 1.0 的时候就已经具备并且延续了下来。


2.0


2.0 我们进入了富文本时代,富文本时代给我们带来了更加丰富的样式,让我们可以更尽情的发挥。而且富文本编辑器还给我们带来了一个新的编辑模式,叫做“所见即所得”。你所编辑的就是你看到的,不再需要你反复去预览,这样可以大大的提升了你的编辑效率。


3.0


3.0 时代,我们完全进入自研的时代,也就是大家近2年多一直在使用的编辑器,我们发现我们还需要在文档里插入一些特殊格式的数据,比如说一个日历,比如说一个投票,比如说一个代码块,这样的一个复杂的数据格式,我们需要能够满足,我们引入了卡片模型,卡片模型让语雀整个编辑器变得更加开放,更加具有连接能力。借助这个能力,我们可以连接互联网,比如说你插入一个网页进来也是可以的,我们也可以在语雀内部去做一些连接,不同的文档之间也可以相互引入,原文档编辑后,引入的文档也会自动更新。

然后,3.0 还给我们带来一个另一个能力,就是多人协同,多人协同让我们语雀编辑器真正的实现了多人同时编辑,成为知识协作的一个工具。

4.0


今天,我们进入 4.0 时代,4.0 编辑器刚刚发布上线,大家可能够直观感受到就是我们的文档表格已经可以多人同时编辑了。经过了半年的研发,我们底层做了一个很大的升级,在架构上也具有更好的灵活性和拓展性。大家知道我们的评论区里面有很多用户给我们提的建议,还有一些问题。虽然不是每个建议我们都能够采纳,但是 4.0 时代我们会给大家呈现更多的精彩,让我们敬请期待。


当然刚刚上线难免会有一些问题,一些用户在讨论区里面说我们的有一些交互变了。虽然这些交互的变化也是经过了我们的一些思考的,但总有不到的地方,我们希望大家不断的给我们提意见。鲜花和鸡蛋我觉得都会让我们变得更好。

Part2. 编辑器成长故事


接下来我给大家介绍一下语雀编辑器的成长故事。

就像刚才所说,其实语雀就是在用户给我们不断的吐槽,给我们不断提建议的一个环境下长大的。那接下来的三个故事,让我们慢慢来看。



故事1. 实时协同


先从第一个故事:实时协同。


在我们语雀商业化第一年的时候,其实我们是不具备这样的一个能力的,我们当时是从我们自己的工作场景中观察,发现多个人同时编辑一篇文档的场景很少,偶尔会用到,频率也很低。但是当时整个市场上对于这个功能是非常关注的,没有这个功能,好像都不好意思跟别人打招呼,是不是这样呢?我们要不要花费巨大的研发成本来实现一个低频的能力呢?我们从来不是一个喜欢去跟风的一个产品,但是我们还是会反思的。我们在想这样的一个功能,这样一个低频的功能,为什么大家如此关注?

我们后来仔细想一想,原来我们看待问题的方式可能有一些问题。


那就是使用频率和重要性。它其实并不能够划等号。我举个例子,一个商场它的消防设施可能并不是经常使用,对吧?我们也希望它一直不要使用,那消防设施其实它很重要。重要性决定我们要不要做这个功能,而使用频率只是决定我们要把它做到什么样子,放在什么位置。

当我们想通了这一点以后,我们觉得我们之前的顾虑和犹豫其实是有问题的。作为一个提倡知识协作的产品,多人同时编辑会在关键时刻提升用户的协作效率。于是我们决定要做实时协同。

实时协同我们怎么设计呢?


我们在实时协同之前,语雀的编辑是一种锁模式,就是一个人在编辑的时候,别人是不能够同时编辑的。这也是基于内容的安全考虑,防止内容和版本变乱,那锁模式它也有锁模式的好处,比如说锁模式比较简单,比较稳定,它的离线也比较友好。我们希望这些特性也能够在在继续延续下来,所以我们额外增加了一个协同模式。

协同模式在团队下,在协同的知识库下面默认开启,你的个人知识库如果加了协作者也会帮你默认开启协作模式。协作模式的好处,就是多个人同时可以同时编辑了,内容实时同步到多个编辑端。但是它也有它的缺点,比如协同模式对网络的要求比较高,有些用户他可能网络比较慢,或者是经常会断,或者是他设置了代理,有可能连不到我们的协同服务器上。这时候我们又增加了一个叫做智能切换的能力,我们可以将你从协同模式切回到锁模式,让你更加稳定的去编辑,这就是语雀编辑器在协同这一块的设计。

实时协同上线了1年多,我们也遇到很多问题。


刚上线的时候其实有很多很难解的问题。比如说丢光标、内容错乱,大家可能偶尔会遇到过,这些问题有很多问题很不好复现。因为你在正常编辑下可能还发现不了,只有那些非常奇怪的一些场景才会出现。然后我们用了接近一年的时间来不断的修bug,改造底层,交互调优,把这些协同的问题慢慢的解掉。在协作模式和锁模式之间实现平滑无感知的智能切换,到去年的下半年语雀的实时协同的功能才逐步的趋于稳定。

故事2. 表格滚动


接下来一个故事是关于表格滚动的


表格编辑器在当初的定位是要把 Excel 20% 的基础功能做到极致,发挥在线的协作优势,将 80% 的数据处理场景做透。这样一个定位决定我们肯定不可能把那个 Excel 的功能全部照搬过来。当然这也不太现实,毕竟人家做了三十几年。既然不能全部照搬,那我们就从最基础的功能去着手。

我们要把基础功能的体验做到极致。那基础体验是什么?


我把它比喻成空气和水,干净的水和清新的空气本身就可以给大家带来一些愉悦的感受。我们希望语雀的编辑器能够像干净的水和空气一样,给编辑者带来最自然的愉悦感受。


怎么样把基础体验做得极致呢?我们说用户会告诉我们,我们常说和用户一起成长,这句话有人可能不太好理解。其实我们的故事就是这样子发生的。

先从表格编辑器中一个最基础的功能来说起,就是滚动。


在你查看表格的时候,你总是需要上下滚动,或者左右滚动来查看你需要的那一行或者一列数据。我们知道受浏览器的一些渲染性能的局限性,表格的滚动可能每个 web 产品的做法可能都不一样。有一种滚动叫做行级滚动,就是一行一行的滚动。一些知名的产品也采取了行级的滚动。我们可以看一看行级滚动是一个什么样的效果。

当你的每一行的内容有一些多的时候,你会发现它的滚动过程中是跳动着的。甚至极端场景,某一行的内容高度超过视窗,你是看不到这行内容底部的内容的。可以自行脑补一下。

然后我们再看一看语雀的像素级滚动


像素级滚动就明显平滑很多,然后这是语雀在滚动这一块做的一个体验。中间为了实现这样的一个特能力,我们其实做了很多技术上的优化方案。比如说根据视窗来按需渲染,比如说我们要实时计算并缓存每一行的高度,等等。

做完像素级滚动以后,我们觉得我们的滚动效果挺好了,然后又有用户跟我们反馈了,说你们的滚动好像有点“晃”,还给我们发来了视频,我们就仔细琢磨了一下。你说的“晃”是什么“晃”。


那其实是这样子的,最初我们做的滚动呢,它是横向和纵向可以自由滚动的,横向和纵向都可以同时滚动。(我拿一个自由滚动的友商产品举个例子)


如果是触摸板的同学可能感受更深一些,你会发现当你横向滚动的时候,你的纵向难免会有一些偏移,所以当你想查看某一行数据的时候,你的视线在这种滚动的时候会受到干扰,你的注意力会聚焦不到你所关注的那一行。

就像刚才所说,其实语雀就是在用户给我们不断的吐槽,给我们不断提建议的一个环境下长大的。那接下来的三个故事,让我们慢慢来看。

于是我们又增加了方向的约束,然后我们看到上面的这张动画,就是我们现在的滚动效果,横向滚动和纵向滚动的时候,它的另一个方向就会锁住。这样的话你的整个滚动会更加稳定,视觉的焦点页能够更加专注,数据的检索会更加高效,这就是我们的滚动。


在语雀表格编辑器中这样的细节体验其实还有很多,我们今天就不一一介绍了。


故事3. 读写分离


第三个故事是关于读写分离的。

我们先说一说读写分离的一个设计初衷。我给大家说两个场景,大家感受一下。

第一个场景,你正在写一篇文章,你的身后站着一堆人在那里看,你是什么样的一个感受,你会不会觉得你的脑袋是完全空白的,不知道该写什么,对不对?

第二个场景,你正在看一篇文章,你发现光标在动,有个人正在写,还有人在删字,还有一些人在调整段落格式,又是一个什么样的阅读感受,你会不会也觉得有些不知所措,这篇文章究竟有没有写完,要不要现在看?


这就是读和写,它本身是两种场景。如果把他们揉在一起,会发生很奇怪的一些体验。所以我们希望对作者来说,他的写能够在一种平静又沉浸的一个创作环境中,他能够无所顾虑的写。而读者他能够放心的去阅读。然后在这两个体验之间,我们用一个“发布/更新”的动作来实现连接。这个发布让我们的作者更加有仪式感,这个动作告诉作者,你的内容将交给读者,由读者来阅读。

这样的一个“读写分离”的设计的使用反馈是怎么样的呢?


我们看一看,首先有一部分用户说挺好的,这样的我可以放心大胆的写了。也有一部分用户会说我一个人写为什么要发布呀?好麻烦呀。是的。同一个体验设计收到截然不同的两种反馈。我们是什么样的感受,读写要不要分离,我们的内心是陷入矛盾的,是坚持还是妥协?问题在哪里?然后我们就去想怎么样去改进这个问题。

分析发现,其实是读者和作者这两个角色的关系问题,我们后来增加了一个自动发布的选项,对于那些读者和作者是同一个角色的时候,我们就开启这种自动发布的选项。比如我们的个人私密的知识库下,我们就默认开启,比如我们的桌面端,桌面端我们就会默认进入写模式,这样的读写分离就会更加友好,我们根据读写两种角色是否为同一个角色来决定读写分离的方式。


好的,3个用户故事我们就讲到这里。

Part3. 编辑器防火墙


接下来我给大家分享一下云雀的编辑器的防火墙:防丢、防乱和防卡。


这一章节之前,在这里向之前所有被语雀编辑器弄丢过、卡过或者弄乱过内容的用户表示一声歉意。确实是我们一开始做的不到,给大家带来了麻烦,那也同时要感谢大家,陪伴我们,帮助我们反馈问题,协助排查问题,才让我们不断的可以去完善产品,来改进体验。


防丢



先从防丢开始说

内容不丢,我们把它当成是一个基础体验的底线。有人说自动保存不就可以了吗?是真的这么简单吗?

我们看一些客观的因素


首先,保存是个大动作,语雀采用的是快照模式的保存,每次保存需要编辑器将全文整理好,发送给服务端,当保存动作和输入动作同时发生的时候,尤其大文档的时候,容易造成输入卡顿。

其次,历史版本过多也容易让人抓狂,不太方便追述。所以我们需要缓存,而缓存是有容量限制的。

再次,网络是个非常不靠谱的东西,断网,弱网,代理网络都有影响。

最后,用户习惯不可琢磨,有些编辑页打开半个月都不关,我们已经中间发布过好几次了,有些同一篇文档开着N个窗口,今天这个窗口写两句,明天那个窗口写两句,这些现实问题给保存带来了非常大的挑战。

我们来看看语雀的自动保存的设计:


为了应对各种状况,我们聘请了5位管家和一位专属快递员,这里的文字比较多,就不给大家读了。这五大管家核心的任务是什么?就是在最合适的时候将你的内容该缓存的缓存,该保存的保存,在你离开的时候,我们会第一时间保存。在你激活的时候第一时间更新内容。

当你离线的时候,我们这位快递员就会在你下一次上线的时候,将你的离线的编辑内容第一时间保存一份到服务端,作为快递员他很贴心,它保存服务端的过程中,如果出现一些网络问题没有成功,它不会将你的离线缓存给删掉。所以只要你存到我们的离线缓存里面,你自己不去主动删,内容基本上是安全的。


这样一个设计之后有很有一些调皮的用户就说那么怎么样才能丢内容呢?这个问题确实挺奇特的。想要丢内容也不是做不到,除非你打开编辑器,一秒不停的编辑,然后断电了。或者离线编辑,然后手动的删除了你的离线缓存。如果你真的这么操作,目前情况下我们是没法保全你的内容的。当然家下来我们会继续完善这里的机制,做到只要你肉眼看到的就不会丢掉。


防乱



下一个防火墙是防乱,常见的乱有哪些呢?


首先最最基本的乱,就是多个人基于同一个版本来编辑。然后后面的保存的覆盖了前面的,这是一种版本错乱。第二个就是你的协同模式下,你的网络可能有些问题,你的数据没有同步到服务端,那有可能造成某些版本的数据的丢失。然后还有一些程序bug,这就不多说了。


刚才说了我们有两种模式,每一种模式遇到问题都不一样,解法也不一样。我们今天就重点说一下锁模式,锁模式为了防乱,我们首先给文档设计了一个版本号,这个版本号会跟随着文档。然后当你保存了一次,他的版本号会加1,然后你每次保存也会携带着你编辑前的基线版本号到服务端,服务端会判断你这个版本号是不是最新的。如果不是最新的,就不会保存成功,会提示冲突。

每次当你打开编辑器的时候,我们会去服务端请求最新的版本,然后来和你本地缓存的基线版本做对比,然后让你基于最新的版本去编辑。

在你离开的时候,我们也会将你的内容第一时间保存到服务端。同时在你编辑的过程中,我们也会每一分钟去服务端请求一下有没有最新的版本。这样的轮询考虑的是一些断网场景,你可能编辑的时候断网了自己都不知道,而在你断网的时候,你的锁权限其实已经收回去了。那别人可能在你断网的过程中编辑了内容,版本已经升上去了。这时候我们我们的轮询会保证你的编辑过程中,即使断网。遇到别人同时编辑的时候,也会在你连网的第一时间,获取最新版本,能让你每次都基于最新的版本去编辑。

但如果出现保存冲突或者有更新的版本怎么办呢?我们会把你的离线编辑的缓存版本备份一份到历史记录里,这样方便你后期手动的把那些离线的内容同步到文档的最新版本中。


防卡


最后说一说如何防卡,常见的卡也是有两种:


一种是流程的卡,我们某些弹窗让你没法往下继续编辑,这种叫做卡住的卡。
还有一种卡就是卡顿的卡,性能不太好,然后编辑不够顺畅。

这两种也都有自己的一些解决方案。


性能卡不用多说,就是不断的去优化性能,然后我们会做一些性能的监控。

流程的卡我们有很多措施,比如说我们的模式智能切换,当你没法连上我们的协同服务器的时候,那我们不希望将你卡住,我们会将你降级到锁模式下去编辑。

我们对锁模式做了很多次升级也都是防卡设计,我们最初是锁人,不同的人不可以同时编辑。但是我们发现这还不够,有些人他是同时打开多个浏览器的,多个窗口之间会相互卡住,我们就开始升级到锁端,锁端又有可能自己把自己也给锁住了,需要切到有权限的编辑端,或者等待1分钟。我们觉得不好,然后我们又加一个不自锁。不自锁还是不够,因为用户就是没法避免两个页面之间不停的来回切,我们不仅要解决锁的问题,还要解决内容同步的问题,我们于是在离开的时候自动解锁,并且把你的内容及时保存上去,在你激活一个编辑器的时候,要同时把最新的内容更新下来。这样的一个锁模式的不断升级,来让我们在锁模式下,尽最大可能减少卡住的情况。

说到卡,在流程的顺滑方面,我们还有一些分级的提醒设计。举个简单的例子,我们的保存有自动保存和手动保存。自动保存我们是不会提示的。因为我们希望你在沉浸的编辑当中自动保存它是背后自然发生的,而手动保存会提示你保存成功,这也是基于一个交互的实时性反馈考虑,同样是保存,有些需要默默完成,有些需要及时响应。

另外,有些异常如果我们能够应付过来,我们就把它以一种消息提醒的方式在右上角出现,会提示你有点小状况,不过我们已经给你处理好了,可以继续放心编辑。如果是我们觉得这个问题特别严重,那我们就会提示一个弹窗出来,让你来决定下一步如何操作。

以上就是语雀在防丢,防乱以及防卡方面所做的一些设计。

Part4. 编辑器的诗与远方


最后一趴给大家分享一下编辑器的诗与远方。





先从这个塔模型开始说:


这是一个我比较喜欢的一个模型:DIKW模型。它给我们揭示知识的演化过程,从数据到信息到知识到人类智慧的一个演进模型。最底层是我们的海量的数据。在数据当中我们可以提炼和观测出一些有用的信息,信息相对数据更加浓缩,然后不同的信息,不同维度的信息,经过一些组织,一些思考,一些推理,能够发现它其中的一些规律,形成我们的知识,知识的运用形成智慧。在这个知识形成的模型当中,我认为编辑器更像一个阶梯。他在每个环节中承担了这种阶梯的作用,让数据升华为信息,让信息升华为知识,是一个工具。可以说编辑器就是促进知识形成的一个工具。我们会不断的增加语雀编辑器在每一个环节的能力,让语雀编辑器不负使命。




再分享一棵树,这颗树我们可以叫他为知识之树。


有一个有意思的问题:知识是什么样子的?大家觉得知识是什么样子的?有人说知识可能是网状的,然后有人说知识是树状的,那究竟是什么样子呢?其实看你怎么样看待这个问题,取决于你的观测角度,从编辑器的角度来看,我们希望知识它更像一棵树,知识的创作从无到有,它其实是一个生长的过程,我们希望它有脉络,有主干,有枝叶,这样子在创作过程中,包括后期的学习中,你能够更更好的把握它的结构。这是从创作和学习的角度考虑,那么一定还有其他的角度,我觉得语雀编辑器的职责就是让知识能够自由的生长成为他应有的样子。

从古至今,人类把文字记在龟壳上,到写在竹签上,再写在纸上,录入到电脑上,网络中,那知识的形态也发生了不断的变化,从图形到文字,到图片,到声音,视频。知识究竟应该什么形态才是最棒的呢?语雀的编辑器也在不断的探索,希望能将知识呈现出她最好的样子呈现给大家。

这就是我的分享,感谢。




语雀大会全场演讲将逐步整理文字稿放出,请关注微信公众号「语雀是什么」





你可能还想看 





玉伯:语雀的历史与未来

子溯:语雀 3.0,知识创作、协同、分享

阿里人都在这里沉淀知识
yuque.com

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存